﻿using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using BCCommon;
using BCCommon.Extensions;
using BCCommon.OAEnums;
using BCData.OA.ApplyOrder;
using BCDto.FMIS.SOBSetting;
using BCDto.MySql.Admin;
using BCDto.OA.ApplyOrder;
using BCService.OA.ApplyOrder.ReimbursementService;
using BCService.OA.ApplyOrder.RemedyCheckInApplyService;
using BCService.OA.ApplyOrder.VacateService;
using BCService.Utils;

namespace BCService.OA.ApplyOrder
{
    /// <summary>
    /// OA申请单服务
    /// </summary>
    public class ApplyOrderService : IApplyOrderService
    {
        private readonly IApplicationContextService applicationContextService;
        private readonly IApplyOrderData applyOrderData;

        public ApplyOrderService(IApplicationContextService applicationContextService,
            IApplyOrderData applyOrderData)
        {
            this.applicationContextService = applicationContextService;
            this.applyOrderData = applyOrderData;
        }

        /// <summary>
        /// 创建一个OA申请单服务
        /// </summary>
        /// <param name="admin">当前员工</param>
        /// <param name="dto">申请信息</param>
        /// <param name="sobSetting">账套信息</param>
        /// <returns></returns>
        public ApplyOrderDto Create(AdminDto admin, ApplyOrderRequestDto dto, SOBSettingDto sobSetting = null)
        {
            switch (dto.Type)
            {
                case OAApplyOrderType.RemedyCheckInApply:
                    return applicationContextService.RequestServices.GetService<IRemedyCheckInApplyOrderService>()?.Create(admin, dto);
                case OAApplyOrderType.Vacate:
                    return applicationContextService.RequestServices.GetService<IVacateApplyOrderService>()?.Create(admin, dto);
                case OAApplyOrderType.Reimbursement:
                    return applicationContextService.RequestServices.GetService<IReimbursementApplyOrderService>()?.Create(admin, dto, sobSetting);
                case OAApplyOrderType.BusinessTrip:
                    break;
                case OAApplyOrderType.Overtime:
                    break;
                case OAApplyOrderType.Probation:
                    break;
                case OAApplyOrderType.Turnover:
                    break;
                case OAApplyOrderType.Procurement:
                    break;
                case OAApplyOrderType.GoodsReception:
                    break;
                default:
                    return new ApplyOrderDto();
            }
            return new ApplyOrderDto();
        }


        /// <summary>
        /// 查看申请单详情
        /// </summary>
        /// <param name="admin">当前登录人员</param>
        /// <param name="applyOrderId">申请单Id</param>
        /// <returns></returns>
        public ApplyOrderViewDto GetDetail(AdminDto admin, long applyOrderId)
        {
            var applyOrder = applyOrderData.GetById(applyOrderId).GetAwaiter().GetResult();
            if (applyOrder == null)
            {
                throw new ArgumentException("申请单信息不存在。");
            }

            switch (applyOrder.Type.AsEnum<OAApplyOrderType>())
            {
                case OAApplyOrderType.RemedyCheckInApply:
                    return applicationContextService.RequestServices.GetService<IRemedyCheckInApplyOrderService>()?.GetDetail(admin, applyOrderId);
                case OAApplyOrderType.Vacate:
                    return applicationContextService.RequestServices.GetService<IVacateApplyOrderService>()?.GetDetail(admin, applyOrderId);
                case OAApplyOrderType.Reimbursement:
                    return applicationContextService.RequestServices.GetService<IReimbursementApplyOrderService>()?.GetDetail(admin, applyOrderId);
                case OAApplyOrderType.BusinessTrip:
                    break;
                case OAApplyOrderType.Overtime:
                    break;
                case OAApplyOrderType.Probation:
                    break;
                case OAApplyOrderType.Turnover:
                    break;
                case OAApplyOrderType.Procurement:
                    break;
                case OAApplyOrderType.GoodsReception:
                    break;
                default:
                    return new ApplyOrderViewDto();
            }
            return new ApplyOrderViewDto();
        }

        /// <summary>
        /// 分页获取申请信息列表
        /// </summary>
        /// <param name="admin">当前登录人员</param>
        /// <param name="pageIndex">分页页码</param>
        /// <param name="pageSize">分页页数</param>
        /// <param name="ascending">是否升序排</param>
        /// <param name="type">申请类型</param>
        /// <param name="status">申请单审核状态</param>
        /// <param name="isMyApproved">是否我审批的</param>
        /// <param name="isMyCreated">由我发起的</param>
        /// <param name="isCopierToMe">抄送给我的</param>
        /// <returns></returns>
        public PageableList<ApplyOrderDto> GetList(AdminDto admin, int pageIndex, int pageSize, bool ascending, OAApplyOrderType? type, OAApplyOrderStatus? status, bool? isMyApproved, bool? isMyCreated, bool? isCopierToMe)
        {
            var (list, count) = applyOrderData.GetAsync(admin.AdminId, pageIndex, pageSize, ascending, type, status, isMyApproved, isMyCreated, isCopierToMe, admin.IsSystemAccount ? (int?)null : admin.CompanyId).GetAwaiter().GetResult();

            return new PageableList<ApplyOrderDto>()
            {
                Count = count,
                Items = list.As<IEnumerable<ApplyOrderDto>>(),
                PageIndex = pageIndex,
                PageSize = pageSize
            };
        }

        /// <summary>
        /// 审核通过
        /// </summary>
        /// <param name="admin">当前管理员</param>
        /// <param name="applyOrderId">申请单号</param>
        /// <returns></returns>
        public ApplyOrderViewDto Pass(AdminDto admin, long applyOrderId)
        {
            var applyOrder = applyOrderData.GetById(applyOrderId).GetAwaiter().GetResult();
            if (applyOrder == null)
            {
                throw new ArgumentException("申请单信息不存在。");
            }
            switch (applyOrder.Type.As<OAApplyOrderType>())
            {
                case OAApplyOrderType.RemedyCheckInApply:
                    return applicationContextService.RequestServices.GetService<IRemedyCheckInApplyOrderService>()?.Pass(admin, applyOrderId);
                case OAApplyOrderType.Vacate:
                    return applicationContextService.RequestServices.GetService<IVacateApplyOrderService>()?.Pass(admin, applyOrderId);
                case OAApplyOrderType.Reimbursement:
                    return applicationContextService.RequestServices.GetService<IReimbursementApplyOrderService>()?.Pass(admin, applyOrderId);
                case OAApplyOrderType.BusinessTrip:
                    break;
                case OAApplyOrderType.Overtime:
                    break;
                case OAApplyOrderType.Probation:
                    break;
                case OAApplyOrderType.Turnover:
                    break;
                case OAApplyOrderType.Procurement:
                    break;
                case OAApplyOrderType.GoodsReception:
                    break;
                default:
                    return new ApplyOrderViewDto();
            }
            return new ApplyOrderViewDto();
        }

        /// <summary>
        ///审核拒绝
        /// </summary>
        /// <param name="admin">当前管理员</param>
        /// <param name="applyOrderId">申请单号</param>
        /// <param name="dto">拒绝原因</param>
        /// <returns></returns>
        public ApplyOrderViewDto Rejected(AdminDto admin, long applyOrderId, ApplyOrderRejectRequestDto dto)
        {
            var applyOrder = applyOrderData.GetById(applyOrderId).GetAwaiter().GetResult();
            if (applyOrder == null)
            {
                throw new ArgumentException("申请单信息不存在。");
            }
            switch (applyOrder.Type.As<OAApplyOrderType>())
            {
                case OAApplyOrderType.RemedyCheckInApply:
                    return applicationContextService.RequestServices.GetService<IRemedyCheckInApplyOrderService>()?.Rejected(admin, applyOrderId, dto);
                case OAApplyOrderType.Vacate:
                    return applicationContextService.RequestServices.GetService<IVacateApplyOrderService>()?.Rejected(admin, applyOrderId, dto);
                case OAApplyOrderType.Reimbursement:
                    return applicationContextService.RequestServices.GetService<IReimbursementApplyOrderService>()?.Rejected(admin, applyOrderId, dto);
                case OAApplyOrderType.BusinessTrip:
                    break;
                case OAApplyOrderType.Overtime:
                    break;
                case OAApplyOrderType.Probation:
                    break;
                case OAApplyOrderType.Turnover:
                    break;
                case OAApplyOrderType.Procurement:
                    break;
                case OAApplyOrderType.GoodsReception:
                    break;
                default:
                    return new ApplyOrderViewDto();
            }
            return new ApplyOrderViewDto();
        }
    }
}
